﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using TestingWP7.BingMapGeoCodeService;
using System.Collections.ObjectModel;
using System.Device.Location;
using System.Threading;
using Microsoft.Phone.Controls.Maps;

namespace TestingWP7
{
    public partial class MainPage : PhoneApplicationPage
    {

        // Constructor
                 
        GeocodeServiceClient _svc;
        GeoCoordinateWatcher _geoCoordinateWatcher;  

        public MainPage()
        {
            InitializeComponent();
          //  street.Visibility = Visibility.Visible;

           _svc = new GeocodeServiceClient();
           _svc.GeocodeCompleted += (s, e) =>
           {
               // sort the returned record by ascending confidence in order for
               // highest confidence to be on the top. Based on the numeration High value is
               // at 0, Medium value at 1 and Low volue at 2
               var geoResult = (from r in e.Result.Results
                                orderby (int)r.Confidence ascending
                                select r).FirstOrDefault();
               if (geoResult != null)
               {
                   this.SetLocation(geoResult.Locations[0].Latitude,
                       geoResult.Locations[0].Longitude,
                       10,
                       true);
               }
           };

           googlemap.CredentialsProvider = new ApplicationIdCredentialsProvider("ApBXPZf5IR94SLXE8nh5FYsb5WHKrH1XPY7428-EqQudseivcWhCROIJvGmtnkAV"); 
             
            // Remove Bing Maps logo and copyrights in order to gain 
            // extra space at the bottom of the map 
            googlemap.LogoVisibility = Visibility.Collapsed; 
            googlemap.CopyrightVisibility = Visibility.Collapsed; 
            // Delcare GeoCoordinateWatcher with high accuracy 
            // in order to use the device's GPS 
            _geoCoordinateWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High); 
            _geoCoordinateWatcher.MovementThreshold = 100; 
            // Subscribe to the device's position changed event 
            // to receive GPS coordinates (longitude and latitude) 
            _geoCoordinateWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(_geoCoordinateWatcher_PositionChanged);
        }

        private void _geoCoordinateWatcher_PositionChanged(object sender,GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => ChangePosition(e));
        }

        private void ChangePosition(GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            SetLocation(e.Position.Location.Latitude,e.Position.Location.Longitude, 10, true);
        }

        private void SetLocation(double latitude, double longitude, int zoomLevel, bool showLocator)
        {
            Microsoft.Phone.Controls.Maps.Platform.Location location = new Microsoft.Phone.Controls.Maps.Platform.Location();
            location.Latitude = latitude;
            location.Longitude = longitude;
            googlemap.SetView(location, zoomLevel);
            bingMapLocator.Location = location;
            if (showLocator)
            {
                locator.Visibility = Visibility.Visible;
            }
            else
            {
                locator.Visibility = Visibility.Collapsed;
            }
        }

        private void ButtonZoomOut_Click(object sender, RoutedEventArgs e)
        {
            googlemap.ZoomLevel--;
        }

        private void ButtonZoomIn_Click(object sender, RoutedEventArgs e)
        {
            googlemap.ZoomLevel++;
        }

        private void btnPlot_Click(object sender, RoutedEventArgs e)
        {
            BingMapGeoCodeService.GeocodeRequest request = new BingMapGeoCodeService.GeocodeRequest();

            

            // Only accept results with high confidence.
            request.Options = new GeocodeOptions()
            {
                Filters = new ObservableCollection<FilterBase>
                {
                    new ConfidenceFilter()
                    {
                        MinimumConfidence = Confidence.High
                    }
                }
            };

         
       

            request.Query = txtAddress.Text;

           //  Make asynchronous call to fetch the geo coordinate data.
            
            _svc.GeocodeAsync(request);

        }

       
    }
    public enum GoogleTileTypes
    {
        Hybrid,
        Physical,
        Street,
        Satellite,
        WaterOverlay
    }

    public class GoogleTile : Microsoft.Phone.Controls.Maps.TileSource
    {
        private int _server;
        private char _mapmode;
        private GoogleTileTypes _tiletypes;

        public GoogleTileTypes TileTypes
        {
            get { return _tiletypes; }
            set
            {
                _tiletypes = value;
                MapMode = MapModeConverter(value);
            }
        }

        public char MapMode
        {
            get { return _mapmode; }
            set { _mapmode = value; }
        }

        public int Server
        {
            get { return _server; }
            set { _server = value; }
        }

        public GoogleTile()
        {
            UriFormat = @"http://mt{0}.google.com/vt/lyrs={1}&z={2}&x={3}&y={4}";
            Server = 0;
        }

        public override Uri GetUri(int x, int y, int zoomLevel)
        {
            if (zoomLevel > 0)
            {
                var Url = string.Format(UriFormat, Server, MapMode, zoomLevel, x, y);
                return new Uri(Url);
            }
            return null;
        }

        

        private char MapModeConverter(GoogleTileTypes tiletype)
        {
            switch (tiletype)
            {
                case GoogleTileTypes.Hybrid:
                    {
                        return 'y';
                    }
                case GoogleTileTypes.Physical:
                    {
                        return 't';
                    }
                case GoogleTileTypes.Satellite:
                    {
                        return 's';
                    }
                case GoogleTileTypes.Street:
                    {
                        return 'm';
                    }
                case GoogleTileTypes.WaterOverlay:
                    {
                        return 'r';
                    }
            }
            return ' ';
        }
    }
}